﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Common;
using Common.Views;

namespace BusinessLogic
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IProductsService" in both code and config file together.
    /// <summary>
    /// This interface contains methods found in the ProductsService which send and get data regarding products 
    /// to and from the Products, ProductCategories, ProductRatings, CommentsProducts and Carts tables in the database.
    /// </summary>
    [ServiceContract]
    public interface IProductsService
    {
        /// <summary>
        /// A method which retreives all the products from the database
        /// </summary>
        /// <returns>A list of all the products found in the database</returns>
        [OperationContract]
        IEnumerable<Product> GetAllProducts();

        /// <summary>
        /// A method which retrieves a list of all the details for a particular product
        /// </summary>
        /// <param name="productID">The ID of the product for which to retrieve the details</param>
        /// <param name="orderID">ID of the order for which to retrieve the details</param>
        /// <returns>A list of all the product details</returns>
        [OperationContract]
        OrdersView GetProductDetails(int productID, Guid orderID);

        /// <summary>
        /// A method which retreives all the comments for a particular product
        /// </summary>
        /// <param name="id">The ID of the product for which to get the comments</param>
        /// <returns>A list of all the comments for a particular product</returns>
        [OperationContract]
        IEnumerable<CommentsProduct> GetCommentsForProduct(int id);

        /// <summary>
        /// A method which adds a product to the user's cart
        /// </summary>
        /// <param name="username">The username of the user for whom the product is added to cart</param>
        /// <param name="productId">The ID of the product to be added to the cart</param>
        /// <param name="qty">The quantity of the product to be added to the cart</param>
        [OperationContract]
        string AddToCart(string username, int productId, int qty);

        /// <summary>
        /// A method which adds a new comment to a product in the database
        /// </summary>
        /// <param name="username">The username of the user who left the comment</param>
        /// <param name="productId">The ID of the product for which the comment is being left</param>
        /// <param name="comment">The comment regarding the product</param>
        [OperationContract]
        void AddComment(string username, int productId, string comment);

        /// <summary>
        /// A method which retreives a list of products in a user's shopping cart
        /// </summary>
        /// <param name="username">The username for which the cart is being retreived</param>
        /// <returns>A list of products in a user's cart</returns>
        [OperationContract]
        IEnumerable<CartView> GetProductsInShoppingCart(string username);

        /// <summary>
        /// A method which retreives the average rating for a particular product
        /// </summary>
        /// <param name="productId">The ID of the product for which to retreive the average rating</param>
        /// <returns>The average rating for a particular product</returns>
        [OperationContract]
        IEnumerable<int> GetRatingForProduct(int productId);

        /// <summary>
        /// A method which adds a new rating for a particular product by a particular user
        /// </summary>
        /// <param name="username">The username who is rating the product</param>
        /// <param name="productId">The ID of the product being rated</param>
        /// <param name="rating">The rating of the product</param>
        /// <returns>A message if the user has already rated the product or null if not</returns>
        [OperationContract]
        string AddRatingForProduct(string username, int productId, int rating);

        /// <summary>
        /// A method which retreives all the Product Categories
        /// </summary>
        /// <returns>A list of all the product categories</returns>
        [OperationContract]
        IEnumerable<ProductCategory> GetCategories();

        /// <summary>
        /// A method which gets a list of products according to their category
        /// </summary>
        /// <param name="categoryId">The ID of the category for which to get the products</param>
        /// <returns>A list of the products with the specified category</returns>
        [OperationContract]
        IEnumerable<Product> GetProductsByCategory(int categoryId);

        /// <summary>
        /// A method which gets a list of products according to the keyword entered
        /// </summary>
        /// <param name="keyword">The word entered by the user which is used to get the products</param>
        /// <returns>A list of the products which contains the specified keyword in their name</returns>
        [OperationContract]
        IEnumerable<Product> GetProductsByName(string keyword);

        /// <summary>
        /// A method which gets a list of products according to the price range
        /// </summary>
        /// <param name="min">The minimum price</param>
        /// <param name="max">The maximum price</param>
        /// <returns>A list of products which have a price between the min and max values</returns>
        [OperationContract]
        IEnumerable<Product> GetProductsByPrice(decimal min, decimal max);

        /// <summary>
        /// A method which gets a list of products sorted by price in ascending order
        /// </summary>
        /// <returns>A list of products sorted by price (ascending)</returns>
        [OperationContract]
        IEnumerable<Product> SortByPriceAsc();

        /// <summary>
        /// A method which gets a list of products sorted by price in descending order
        /// </summary>
        /// <returns>A list of products sorted by price (descending)</returns>
        [OperationContract]
        IEnumerable<Product> SortByPriceDesc();

        /// <summary>
        /// A method which gets a list of products sorted by the date listed (latest first)
        /// </summary>
        /// <returns>A list of products sorted by the date listed (latest first)</returns>
        [OperationContract]
        IEnumerable<Product> SortByDateAsc();
    }
}
